package org.roger.sort;

import java.io.IOException;

import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.BinaryDocValues;
import org.apache.lucene.search.FieldCache;
import org.apache.lucene.search.FieldComparator;
import org.apache.lucene.search.FieldComparatorSource;
import org.roger.util.DistanceUtil;

/**
 * 自定义距离排序（文档当前的点到（x,y）的距离）
 * @param x 横坐标
 * @param y 纵坐标
 * @author luoweiyi
 */
public class DistanceComparatorSource extends FieldComparatorSource{
	
	private int x;
	private int y;
	
	public DistanceComparatorSource(int x,int y){
		this.x = x;
		this.y = y;
	}

	@Override
	public FieldComparator<?> newComparator(String fieldname, int numHits,
			int sortPos, boolean reversed) throws IOException {
		// TODO Auto-generated method stub
		return new DistanceScoreDocLookupComparator(fieldname,numHits);
	}
	
	private class DistanceScoreDocLookupComparator extends FieldComparator<Double>{

		private int[] xDoc, yDoc;
		
		private double[] values;
		
		private double bottom;//评分结果最低
		
		String fieldName;
		
		public DistanceScoreDocLookupComparator(String fieldName,int numHits){
			values = new double[numHits];
			this.fieldName = fieldName;
		}
		
		@Override
		public int compare(int slot1, int slot2) {
			if(values[slot1] > values[slot2])return 1;
			if(values[slot1] < values[slot2])return -1;
			return 0;
		}
		
		@Override
		public void setBottom(int slot) {
			bottom = values[slot];
		}

		@Override
		public int compareBottom(int doc) throws IOException {
			double dis = DistanceUtil.getDistance(xDoc[doc]-x, yDoc[doc]-y);
			if(bottom > dis) return 1;
			if(bottom < dis) return -1;
			return 0;
		}

		@Override
		public int compareTop(int doc) throws IOException {
			return 0;
		}

		@Override
		public void copy(int slot, int doc) throws IOException {
			//得到文档到点（x,y）的实际距离
			values[slot] = DistanceUtil.getDistance(xDoc[doc]-x, yDoc[doc]-y);
		}

		@Override
		public FieldComparator<Double> setNextReader(AtomicReaderContext context)
				throws IOException {
			int numDoc = context.reader().numDocs();
			
			//得到文档所有的坐标值
			xDoc = new int[numDoc];
			yDoc = new int[numDoc];
//			for(int i = 0; i < numDoc; i++){
//				String location = context.reader().document(i).get(fieldName);
//				xDoc[i] = Integer.parseInt(location.split(",")[0]);
//				yDoc[i] = Integer.parseInt(location.split(",")[1]);
//			}
			//通过缓存域取数据
			BinaryDocValues bits = FieldCache.DEFAULT.getTerms(context.reader(), fieldName,true);
			for(int i = 0; i < numDoc; i++){
				String location = bits.get(i).utf8ToString();
				xDoc[i] = Integer.parseInt(location.split(",")[0]);
				yDoc[i] = Integer.parseInt(location.split(",")[1]);
			}
			return this;
		}

		@Override
		public Double value(int slot) {
			return new Double(values[slot]);
		}

		@Override
		public void setTopValue(Double value) {
			// TODO Auto-generated method stub
			
		}
	}
}
